

// 初始化 WebSocket
// 创建一个 WebSocket 实例
// let websocket = new WebSocket("ws://localhost:8081/message_ctrl");
let websocket = new WebSocket("ws://" + location.host + "/message_ctrl");

websocket.onopen = function () {
    console.log("WebSocket 连接成功！");
}

websocket.onmessage = function (e) {
    console.log("WebSocket 收到消息：" + e.data);
    // 此时收到的 e.data 是一个 json 字符串，需要转换成 js 对象
    let res = JSON.parse(e.data);
    if (res.type == 'message') {
        // 处理消息响应
        handleMessage(res);
    } else {
        // res 的 type 出错
        console.log("响应类型错误！");
    }
}

// 把客户端收到的消息，展示到对应的会话列表，以及右侧的消息列表中（选中的状态）
function handleMessage(res) {
    // 1. 根据响应中的 sessionId 获取当前会话对应的 li 标签
    //    如果 li 标签不存在，则创建一个新的
    let curSessionLi = findSessionLi(res.sessionId);
    if (curSessionLi == null) {
        // 会话不存在，需要创建一个新的 li 标签，来表示这个会话
        curSessionLi = document.childElement('li');
        curSessionLi.setAttribute('message-session-id', res.sessionId);
        // 设置头像、用户名
        initLi(res.fromId, curSessionLi);


        // 给这个 li 标签绑定一个点击事件
        curSessionLi.onclick = function () {
            clickSession(curSessionLi);
        }
    }

    // 2. 把收到消息的会话置顶
    let sessionListUL = document.querySelector('#session-list');
    sessionListUL.insertBefore(curSessionLi, sessionListUL.children[0]);
    // 3. 如果当前收到消息的会话处于被选中状态，则把当前消息更新到消息列表中
    //     新增消息的同时，需要保证滚动条位于底部
    if (curSessionLi.className == 'selected') {
        let messageShowDiv = document.querySelector('.right .message-show');
        addMessage(messageShowDiv, res)
        scrollBottom(messageShowDiv);
    }

    // TODO 其他操作，还可以在会话列表上提示未读消息的数量（红色数字）
}


function initLi(userId, sessionLi) {
    console.log("initLi: userId = " + userId);

    jQuery.ajax({
        url: "user/getuserinfobyuid",
        type: "POST",
        data: {
            "uid": userId
        },
        success: function (res) {
            if (res.code == 200 && res.data != null) {
                // 设置用户头像
                var photo = ""
                if (res.data.photo != null && res.data.photo != '') {
                    photo = "/photo/" + res.data.photo;
                } else {
                    photo = "/img/avatar.png";
                }

                sessionLi.innerHTML += '<img class="avtar-session-user" src="' + photo + '" alt="Avatar">';

                // 设置用户名
                var username = '';
                if (res.data.nickname != null && res.data.nickname != 'undefined') {
                    username = res.data.nickname;
                } else {
                    username = res.data.username;
                }
                sessionLi.innerHTML += '<h3 class="username" user-id="' + res.data.id + '">' + username + '</h3>';
            }
            else {
                console.log("初始化 li 标签失败！" + res.msg);
                // location.href = "private_message.html";
            }
        }
    });


}

function findSessionLi(targetSessionId) {
    // 获取所有会话列表
    let sessionLis = document.querySelectorAll('#session-list li');
    for (let li of sessionLis) {
        let sessionId = li.getAttribute("message-session-id");
        if (sessionId == targetSessionId) {
            return li;
        }
    }
    // 如果新用户给当前用户发信息，则会触发这种情况
    return null;
}

websocket.onclose = function () {
    console.log("WebSocket 连接关闭！");
}

websocket.onerror = function () {
    console.log("WebSocket 连接异常！");
}

/*
// 实现消息发送和接收
function initSendButton() {
    // 1. 获取发送按钮和消息输入框
    let sendButton = document.querySelector('.right .ctrl button');
    let messageInout = document.querySelector('.right .message-input')
    // 2. 给发送按钮注册一个点击事件
    sendButton.onclick = function () {
        // 判断内容是否为空
        if (messageInout.value == null || messageInout.value == '') {
            console.log("消息为空！");
            return;
        }
        // 获取当前选中的 li 标签中的 sessionId
        let selectedLi = document.querySelector('#session-list .selected');
        if (selectedLi == null) {
            // 没有标签被选中
            return;
        }

        let sessionId = selectedLi.getAttribute('message-session-id');
        // 3. 构造 json 数据
        let req = {
            "type": 'message',
            "sessionId": sessionId,
            "content": messageInout.value
        }
        // 4. 通过 WebSocket 发送，需要手动把 req 转换为 json 字符串
        req = JSON.stringify(req);
        console.log("[WebSocket] 发送：" + req);
        websocket.send(req);

        // 5. 清空之前的输入框
        messageInout.value = '';
    }
}

initSendButton();
*/

// 修改 initSendButton 函数，添加 Enter 键的按下事件监听
function initSendButton() {
    // 1. 获取发送按钮和消息输入框
    let sendButton = document.querySelector('.right .ctrl button');
    let messageInput = document.querySelector('.right .message-input');

    // 2. 给发送按钮注册一个点击事件
    sendButton.onclick = function () {
        sendMessage();
    }

    // 3. 给消息输入框添加键盘按下事件监听
    messageInput.addEventListener('keydown', function (event) {
        if (event.keyCode === 13 && !event.shiftKey) {
            event.preventDefault(); // 阻止默认的回车键行为（换行）
            sendMessage(); // 调用发送消息函数
        }
    });
}

// 发送消息的函数
function sendMessage() {
    // 获取消息编辑框的内容
    let messageInput = document.querySelector('.right .message-input');
    let messageText = messageInput.value.trim();

    if (messageText !== "") {
        // 构造发送消息的逻辑
        // 可以将消息显示在聊天窗口中，然后清空编辑框内容
        // 例如：displayMessage(messageText);
        // 清空消息编辑框
        messageInput.value = '';

        // 获取当前选中的会话的 sessionId
        let selectedLi = document.querySelector('#session-list .selected');
        if (selectedLi) {
            let sessionId = selectedLi.getAttribute('message-session-id');
            // 构造 JSON 数据并通过 WebSocket 发送
            let req = {
                "type": 'message',
                "sessionId": sessionId,
                "content": messageText
            };
            req = JSON.stringify(req);
            console.log("[WebSocket] 发送：" + req);
            websocket.send(req);
        }
    }
}

initSendButton();


// =================================



// 从服务器获取到用户登录信息

function getUserInfo() {
    jQuery.ajax({
        url: "user/getuserinfo",
        type: "POST",
        data: {},
        success: function (res) {
            if (res.code == 200 && res.data != null) {
                // 获取登录用户信息成功！

                // 设置 uid 属性
                jQuery("#login-user").attr("login-user-id", res.data.id);


                // 设置头像
                if (res.data.photo != null && res.data.photo != '') {
                    jQuery("#avatar-img").attr("src", "/photo/" + res.data.photo);
                } else {
                    jQuery("#avatar-img").attr("src", "/img/avatar.png");
                }

                // 用户名或昵称
                if (res.data.nickname != null && res.data.nickname != 'undefined') {
                    jQuery("#author").html(res.data.nickname);
                } else {
                    jQuery("#author").html(res.data.username);
                }

            } else {
                // 获取失败
                alert("当前用户未登录！");
                location.href = "login.html";
            }
        }
    });
}

getUserInfo();

function getSessionList() {
    jQuery.ajax({
        url: "message_session/get_session_list",
        type: "POST",
        data: {},
        success: function (res) {
            if (res.code == 200 && res.data.length >= 0) {
                // 1. 清空之前的会话列表
                let sessionListUL = document.querySelector('#session-list');
                sessionListUL.innerHTML = '';
                // 2. 遍历响应的数组, 针对结果来构造页面
                for (let session of res.data) {

                    let li = document.createElement('li');
                    // 把会话 id 保存到 li 标签的自定义属性中. 
                    li.setAttribute('message-session-id', session.sessionId);

                    // 设置用户头像

                    var photo = ""
                    if (session.friend.photo != null && session.friend.photo != '') {
                        photo = "/photo/" + session.friend.photo;
                    } else {
                        photo = "/img/avatar.png";
                    }

                    li.innerHTML += '<img class="avtar-session-user" src="' + photo + '" alt="Avatar">';

                    // 设置用户名
                    var username = '';
                    if (session.friend.nickname != null && session.friend.nickname != 'undefined') {
                        username = session.friend.nickname;
                    } else {
                        username = session.friend.username;
                    }

                    li.innerHTML += '<h3 class="username" user-id="' + session.friend.friendId + '">' + username + '</h3>';
                    sessionListUL.appendChild(li);

                    // 给 li 标签新增点击事件
                    li.onclick = function () {
                        // 这个写法, 就能保证, 点击哪个 li 标签
                        // 此处对应的 clickSession 函数的参数就能拿到哪个 li 标签. 
                        clickSession(li);
                    }
                }

                // 等所有会话列表添加完成后，再检查url中的参数，根据里面的参数来判断是否新增会话
                checkURL();

            } else if (res.code != 200) {
                console.log('获取会话列表失败！' + res.msg);
            }
        }
    });
}

getSessionList();

function clickSession(currentLi) {

    // 1. 设置高亮
    let allLis = document.querySelectorAll('#session-list>li');
    activeSession(allLis, currentLi);


    // 2. 获取指定会话的历史消息
    let sessionId = currentLi.getAttribute("message-session-id");
    // 获取 user-id 属性的方法
    let userIdElement = currentLi.querySelector('.username');
    let friendId = userIdElement ? userIdElement.getAttribute('user-id') : null;

    // 调用获取历史消息的函数
    getHistoryMessage(sessionId, friendId);
}


function activeSession(allLis, currentLi) {
    // 这里的循环遍历, 更主要的目的是取消未被选中的 li 标签的 className
    for (let li of allLis) {
        if (li == currentLi) {
            li.className = 'selected';
        } else {
            li.className = '';
        }
    }
}

// 用于获取指定会话的历史消息
function getHistoryMessage(sessionId, friendId) {
    console.log('获取历史消息: sessionId = ' + sessionId + ', friendId: ' + friendId);
    // 1. 先清空右侧列表中的已有内容
    let titleDiv = document.querySelector('.right .title');
    titleDiv.innerHTML = '';
    let messageShowDiv = document.querySelector('.right .message-show');
    messageShowDiv.innerHTML = '';

    // 2. 重新设置会话的标题
    let selectedH3 = document.querySelector('#session-list .selected>h3');
    if (selectedH3 != null) {
        titleDiv.innerHTML = selectedH3.innerHTML;
    }

    // 3. 向后端发送，获取该会话的历史消息
    jQuery.ajax({
        url: "message/get_message_list",
        type: "POST",
        data: {
            "sessionId": sessionId,
            "friendId": friendId
        },
        success: function (res) {
            if (res.code == 200 && res.data.length >= 0) {
                // 获取消息成功！
                for (let message of res.data) {
                    addMessage(messageShowDiv, message);
                }

                // 加个操作：在构造好消息列表之后，控制滚动条，自动滚动到最下方。
                scrollBottom(messageShowDiv);
            } else {
                console.log(res.code);
                alert("获取历史消息失败！" + res.msg);
                location.href = "private_message.html";
            }
        }
    });
}

function scrollBottom(element) {
    // 将滚动条滚动到元素底部
    element.scrollTop = element.scrollHeight;
}

function addMessage(messageShowDiv, message) {
    // 使用这个div表示一条消息
    let messageDiv = document.createElement('div');
    // 针对当前消息是不是自己发的决定靠右还是靠左
    // TODO
    let userDiv = document.querySelector('.left .user');
    let loginUserId = userDiv.getAttribute("login-user-id");
    console.log("loginUserId: " + loginUserId);

    // 获取当前用户的头像
    let loginUserImg = userDiv.querySelector('img.avatar-img');
    let loginUserImgSrc = loginUserImg.getAttribute('src');
    console.log(loginUserImgSrc); // 这将会输出图片的src属性值

    // 获取对话对象的头像
    let liElement = document.querySelector('.selected');
    let SessionImg = liElement.querySelector('img.avtar-session-user');
    let SessionImgSrc = SessionImg.getAttribute('src');
    console.log(SessionImgSrc); // 输出头像的src属性值



    if (message.fromId == loginUserId) {
        // 消息是自己发的，靠右
        messageDiv.className = "message message-right";
        messageDiv.innerHTML = '<div class="box-header">'
            + '<span style="color: green;">' + message.createTime + '</span>'
            + '<img class="avtar-session-user" src="' + loginUserImgSrc + '" alt="Avatar">'
            + '</div>'
            + '<div class="box">'
            + '<p>' + message.content + '</p>'
            + '</div>';

    } else {
        // 消息是别人发的，靠左
        messageDiv.className = "message message-left";
        messageDiv.innerHTML = '<div class="box-header">'
            + '<img class="avtar-session-user" src="' + SessionImgSrc + '" alt="Avatar">'
            + '<span style="color: green;">' + message.createTime + '</span>'
            + '</div>'
            + '<div class="box">'
            + '<p>' + message.content + '</p>'
            + '</div>';
    }


    messageShowDiv.appendChild(messageDiv);
}


// ====================================


// 检查当前url是否存在参数uid，如果有，则向指定用户 uid 发起会话
function checkURL() {
    // 从 url 中获取 uid
    var uid = getParamByKey("uid");
    console.log("checkURL: uid = " + uid);

    // 没有 uid 参数
    if (uid == null) {
        return;
    }

    // 有 uid 参数
    createSession(uid);
}


// 通过url参数触发的创建的会话
function createSession(friendId) {
    // 1. 判断当前这个好友是否有对应会话
    // 参数是用户名，返回值是li标签，找到了返回会话列表中的标签，否则返回null
    let sessionLi = findSessionByUid(friendId);
    let sessionListUL = document.querySelector('#session-list');
    if (sessionLi != null) {
        // 2. 如果存在，则把这个会话设置为选中状态，获取历史消息，并且置顶
        // 使用 insertBefore 把这个 li 标签放到最前面
        sessionListUL.insertBefore(sessionLi, sessionListUL.children[0]);

        // 置顶，直接调用 clickSession
        // clickSession(sessionLi);
        // 或者模拟点击 
        sessionLi.click();
    } else {
        // 3. 如果不存在，就创建一个新会话（创建li标签 + 通知服务器）
        sessionLi = document.createElement("li");

        // 初始化头像、用户名
        initLi(friendId, sessionLi);

        // 把标签置顶
        sessionListUL.insertBefore(sessionLi, sessionListUL.children[0]);
        // 注册点击事件
        sessionLi.onclick = function () {
            clickSession(sessionLi);
        }

        console.log("发送信息给服务器，添加会话到数据库");
        // 发送信息给服务器，添加会话到数据库
        addSession(friendId, sessionLi);
    }
}

function findSessionByUid(uid) {
    console.log("findSessionByUid: uid = " + uid);
    // 先获取到会话列表中的所有li标签
    // 然后依次查找对比 li 标签中的 username
    let sessionList = document.querySelectorAll('#session-list>li');
    console.log(sessionList.length);
    for (let sessionLi of sessionList) {
        // 获取到该 li 标签中的 h3 标签，获取userId
        let h3 = sessionLi.querySelector("h3");
        var curUserId = h3.getAttribute("user-id");
        console.log("findSessionByUid: uid" + uid + ", user-id: " + curUserId);
        if (uid == curUserId) {
            return sessionLi;
        }
    }
    return null;
}

// friendId 是构造 HTTP 请求的必备信息
// 当服务器在数据库中新建会话之后，将返回的 sessionId 设置到 sessionLi 标签中
function addSession(friendId, sessionLi) {
    jQuery.ajax({
        url: "message_session/add_session",
        type: "POST",
        data: {
            "friendId": friendId
        },
        success: function (res) {
            if (res.code == 200 && res.data > 0) {
                console.log("会话创建成功！");
                // 在 li 标签中添加 sessionId
                sessionLi.setAttribute('message-session-id', res.data);

                // 构建完li标签后
                // 模拟点击 
                sessionLi.click();
            } else {
                alert("创建会话失败！" + res.msg);
                location.href = "private_message.html";
            }
        }
    });
}
